package org.example.lotterysystem.service.activitystatus.impl;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.example.lotterysystem.common.domain.dto.ConvertActivityStatusDTO;
import org.example.lotterysystem.common.errorcode.ErrorCodeConstants;
import org.example.lotterysystem.common.exception.ServiceException;
import org.example.lotterysystem.service.ActivityService;
import org.example.lotterysystem.service.activitystatus.ActivityStatusManager;
import org.example.lotterysystem.service.activitystatus.operater.AbstractActivityOperator;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Component
@Slf4j
public class ActivityStatusManagerImpl implements ActivityStatusManager {

    @Resource
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();

    @Resource
    ActivityService activityService;

    /**
     * 扭转状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)   //事务
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        if(CollectionUtils.isEmpty(operatorMap)){
            log.warn("operatorMap 为空！");
            return;
        }
        Map<String, AbstractActivityOperator> current=new HashMap<>(operatorMap);
        Boolean update = false;
        // 先处理：人员、奖品
        update = processConvertStatus(convertActivityStatusDTO, current, 1);
        // 后处理：活动
        update = processConvertStatus(convertActivityStatusDTO, current, 2) || update;
        // 更新缓存
        if (update) {
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }
    }

    /**
     * 回滚状态
     */
    @Override
    public void rollbackHandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        for(AbstractActivityOperator operator:operatorMap.values()){
            //将状态转换回去
            operator.convert(convertActivityStatusDTO);
        }
        //Redis更新
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
    }

    /**
     * 处理状态扭转
     * @param convertActivityStatusDTO
     * @param current
     * @param sequence
     * @return
     */
    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> current,
                                         int sequence) {
        boolean update=false;
        //遍历current
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator = current.entrySet().iterator();
        while(iterator.hasNext()){
            AbstractActivityOperator operator = iterator.next().getValue();

            //Operator是否需要转换
            if (operator.sequence() != sequence
                    || !operator.needConvert(convertActivityStatusDTO)) {
                continue;
            }

            //需要转换
            if (!operator.convert(convertActivityStatusDTO)) {
                log.error("{}状态转换失败！", operator.getClass().getName());
                throw new ServiceException(ErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }

            //current删除当前Operator
            iterator.remove();
            update = true;
        }

        //返回
        return update;
    }

}
